using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;

namespace IQIGame.Onigao.GamePlay
{
    public class EntityParamDictionaryConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(IReadOnlyDictionary<EntityDynamicParamType, BaseEntityDynamicParam>);
        }

        public override bool CanWrite => false;

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var result = new Dictionary<EntityDynamicParamType, BaseEntityDynamicParam>();

            var myDictionayJObject = JObject.Load(reader);
            foreach (var property in myDictionayJObject.Properties())
            {
                EntityDynamicParamType paramType = (EntityDynamicParamType)Enum.Parse(typeof(EntityDynamicParamType), property.Name);
                BaseEntityDynamicParam entityParam = null;
                switch (paramType)
                {
                    case EntityDynamicParamType.PatrolPath:
                        entityParam = property.Value.ToObject<EntityParamPatrolPath>(serializer);
                        result.Add(paramType, entityParam);
                        break;
                    case EntityDynamicParamType.TriggerRect:
                        entityParam = property.Value.ToObject<EntityParamTriggerRect>(serializer);
                        result.Add(paramType, entityParam);
                        break;
                    case EntityDynamicParamType.Ledge:
                        entityParam = property.Value.ToObject<EntityParamLedgeData>(serializer);
                        result.Add(paramType, entityParam);
                        break;
                    case EntityDynamicParamType.Elevator:
                        entityParam = property.Value.ToObject<EntityParamElevator>(serializer);
                        result.Add(paramType, entityParam);
                        break;
                    case EntityDynamicParamType.House:
                        entityParam = property.Value.ToObject<EntityParamHouse>(serializer);
                        result.Add(paramType, entityParam);
                        break;
                    case EntityDynamicParamType.EntitySwitchState:
                        entityParam = property.Value.ToObject<EntityParamSwitchState>(serializer);
                        result.Add(paramType, entityParam);
                        break;
                    case EntityDynamicParamType.Area:
                        entityParam = property.Value.ToObject<EntityParamArea>(serializer);
                        result.Add(paramType, entityParam);
                        break;
                    case EntityDynamicParamType.CheckPoint:
                        entityParam = property.Value.ToObject<EntityParamCheckPoint>(serializer);
                        result.Add(paramType, entityParam);
                        break;
                    case EntityDynamicParamType.None:
                        throw new JsonSerializationException($"Unexpected EntityDynamicParamType: {paramType}");
                    default:
                        throw new JsonSerializationException($"Unexpected EntityDynamicParamType: {paramType}");
                }
            }

            return result;
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException("Unnecessary because CanWrite is false. The type will skip the converter.");
        }
    }
}
